package p2p

import (
	"context"
	"flag"
	"goqk/core/events"
	"log"
	"time"

	"github.com/smallnest/rpcx/client"
)

// HandleReply function
type HandleReply func(reply *Reply)

// Client type.
type Client struct {
	option        client.Option
	discovery     client.ServiceDiscovery
	ReplyCallback HandleReply
}

// Prepare - 运行客户端
func (lc *Client) Prepare() {
	flag.Parse()

	lc.discovery = client.NewMultipleServersDiscovery([]*client.KVPair{{Key: *Config.Address}})
	// lc.discovery = client.NewPeer2PeerDiscovery("tcp@"+*P2PConfig.Address, "")

	lc.option = client.DefaultOption
	lc.option.ReadTimeout = 20 * time.Second
	// option.TLSConfig = &tls.Config{
	// 	InsecureSkipVerify: true,
	// }
	lc.option.Heartbeat = true
	lc.option.HeartbeatInterval = time.Second
	// events.Subscribe("LedgerService", "Broadcast", func(e events.Event) {
	// 	// lc.Broadcast("", )
	// })
}

// Broadcast function
func (lc *Client) Broadcast(serverName string, args *Args, reply *Reply) {
	// xclient := client.NewXClient("Arith", client.Failover, client.RoundRobin, d, client.DefaultOption)
	xclient := client.NewXClient(serverName, client.Failover, client.RoundRobin, lc.discovery, lc.option)
	// xclient.Auth("rosefinch tGzv3JOkF0XG5Qx2TlKWIA")
	defer xclient.Close()
	// xclient.Auth("rosefinch abcdefg1234567")

	// for {
	// reply := &Reply{}
	// ctx := context.WithValue(context.Background(), share.ReqMetaDataKey, make(map[string]string))
	// err := xclient.Call(ctx, "Mul", args, reply)
	// ctx := context.WithValue(context.Background(), share.ReqMetaDataKey, map[string]string{"aaa": "from client"})
	// ctx = context.WithValue(ctx, share.ResMetaDataKey, make(map[string]string))
	err := xclient.Broadcast(context.Background(), "HandleCommitTransaction", args, reply)
	if err != nil {
		log.Fatalf("failed to call: %v", err)
	}

	// callback.Get
	go lc.ReplyCallback(reply)
	// go events.Publish(events.Event{Sender: "", Flag: "", Context: []byte("")})
	// time.Sleep(1e9)
	// }
}

// AsynData function
func (lc *Client) AsynData(serverName string, args *Args, reply *Reply) {
	xclient := client.NewXClient(serverName, client.Failover, client.RandomSelect, lc.discovery, lc.option)
	xclient.Auth("rosefinch tGzv3JOkF0XG5Qx2TlKWIA")
	defer xclient.Close()

	for {
		err := xclient.Broadcast(context.Background(), "CommitTransaction", args, reply)
		if err != nil {
			log.Fatalf("failed to call: %v", err)
		}

		// lc.ReplyCallback(reply)
		go events.Publish(events.Event{Sender: "", Flag: "", Context: []byte("")})
		log.Printf("%s", reply)
		time.Sleep(1e9)
	}
}
